#-*- coding: utf-8 -*-

import urllib
import threading
import json
import httplib
import logging
import datetime
import HTMLParser
from func import *

class Chat(object):
    def __init__(self):
        self.uid = ''
        self.cid = ''
        self.lock_post = threading.Lock()
        self.lock_long = threading.Lock()
        self.LongPolling = None
        self.isStart = False

        self.event_newMessage = None
        self.event_startChat = None
        self.event_stopChat = None
        self.event_startTyping = None
        self.event_stopTyping = None

        self.parser = HTMLParser.HTMLParser()

        self.timer = None
        self.autostop = False

    #region service
    #отправка post
    def post(self, params):
        text = ''
        with self.lock_post:
            try:
                headers = {"Content-type": "application/x-www-form-urlencoded",
                           "X-Requested-With": "XMLHttpRequest"}
                conn = httplib.HTTPConnection("chatvdvoem.ru:80")
                param = dict((k, unicode(v).encode('utf-8')) for k, v in params.iteritems())
                conn.request('POST', '/send', urllib.urlencode(param), headers)
                f = conn.getresponse()
                text = f.read()
                #print 'post resposn '+text
            except Exception, ex:
                logging.error(str(ex))
            finally:
                return text

    #выполнение событий, в отдельном потоке
    @create_thread('events')
    def run(self, name, *args):
        if name:
            name(*args)
    #endregion

    #запуск
    @create_thread('new')
    def start(self):
        try:
            #если есть юид - то ожидаем
            if self.uid:
                self.wait_opponent()
                return

            data = json.loads(self.post({'action': 'get_uid'}))
            if data['result'] == 'ok':
                self.uid = data['uid']
                self.get_event()
                self.wait_opponent()
        except Exception, ex:
            print ex

    #ожидание
    @create_thread()
    def wait_opponent(self):
        data = self.post({"action": 'wait_opponent', "uid": self.uid})
        if data == 'error uid':
            self.uid = ''
            threading.Timer(0.100, self.start)

    #отправка подтверждения
    @create_thread()
    def send_ready(self, uid, cid):
        data = self.post({'action': 'set_ready', 'uid': uid, 'cid': cid})
        if data == 'reconnect':
            threading.Timer(0.100, self.start)

    #ожидание оппоненка
    @create_thread()
    def new_opponent(self, cid):
        self.post({'action': 'wait_new_opponent', 'uid': self.uid, 'cid': cid})

    #достало комментить очевидные вещи
    @create_thread()
    def stop(self):
        if self.cid:
            self.post({"action": 'stop_chat', "uid": self.uid, "cid": self.cid, "opponent_init": '0'})
    @create_thread('send')
    def send(self, msg):
        #print 'send '+msg
        if self.cid:
            self.post({'action': 'send_message', 'uid': self.uid, 'cid': self.cid, 'message': msg})

    @create_thread()
    def start_typing(self):
        self.post({"action": 'start_typing', "uid": self.uid, "cid": self.cid})

    @create_thread()
    def stop_typing(self):
        self.post({"action": 'stop_typing', "uid": self.uid, "cid": self.cid})

    @create_thread('LongPolling', True)
    def get_event(self):
        self.__get_event()

    def __get_event(self):
        try:
            headers = {"Content-type": "application/x-www-form-urlencoded",
                       "X-Requested-With": "XMLHttpRequest"}
            conn = httplib.HTTPConnection("chatvdvoem.ru:80", timeout=40)
            conn.request('POST','/events?'+self.uid, urllib.urlencode({'action':'get'}), headers)
            resp = conn.getresponse().read()

            #print 'LongPolling'+resp

            threading.Timer(0.1, self.__get_event).start()
            data = json.loads(resp)
            with self.lock_long:
                if data['action']=='start_typing': self.run(self.event_startTyping)
                if data['action']=='stop_typing': self.run(self.event_stopTyping)
                if data['action']=='new_message': self.run(self.event_newMessage, data['user'], self.parser.unescape(data['message']))
                if data['action']=='get_ready': self.send_ready(self.uid, data['cid'])
                if data['action']=='start_chat':
                    self.cid = data['cid']
                    self.run(self.event_startChat)
                    self.isStart = True
                if data['action']=='stop_chat':
                    self.cid=''
                    self.run(self.event_stopChat)
                    self.isStart = False
        except:
            pass


# http://chatvdvoem.ru/js/chat.js?14